﻿using PublicEntity;
using SocketServer.Model;
using SocketServer.SocketAttribute;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SocketServer.WebSocketAction
{
    /// <summary>
    /// Socket服务方法的基类
    /// </summary>
    /// <remarks>
    /// 继承该接口的所有子类首次创建在WebSocketServerStartHelper的LoadAction方法中
    /// </remarks>
    public class WebSocketServerActionBase : IWebSocketServerAction
    {
        #region 自定义属性|方法给子类方便操作
        /// <summary>
        /// 获取页码
        /// </summary>
        protected int PageIndex
        {
            get
            {
                var pageIndex = this.Request?.Parameters?.FirstOrDefault(t => "pageIndex".Equals(t.Name));
                if (pageIndex != null)
                {
                    if (int.TryParse(pageIndex.Value, out var result))
                    {
                        return result;
                    }
                }
                return 1;
            }
        }

        /// <summary>
        /// 页码行数
        /// </summary>
        protected int PageSize
        {
            get
            {
                var size = this.Request?.Parameters?.FirstOrDefault(t => "size".Equals(t.Name));
                if (size != null)
                {
                    if (int.TryParse(size.Value, out var result))
                    {
                        return result;
                    }
                }
                return 20;
            }
        }

        /// <summary>
        /// 开始时间
        /// </summary>
        protected DateTime? StartTime
        {
            get
            {
                var time = this.Request?.Parameters?.FirstOrDefault(t => "StartTime".Equals(t.Name));
                if (time != null)
                {
                    if (DateTime.TryParse(time.Value, out var result))
                    {
                        return result;
                    }
                }
                return null;
            }
        }

        /// <summary>
        /// 结束时间
        /// </summary>
        protected DateTime? EndTime
        {
            get
            {
                var time = this.Request?.Parameters?.FirstOrDefault(t => "EndTime".Equals(t.Name));
                if (time != null)
                {
                    if (DateTime.TryParse(time.Value, out var result))
                    {
                        return result;
                    }
                }
                return null;
            }
        }

        private string _SelectWhere = string.Empty;
        /// <summary>
        /// 查询条件
        /// </summary>
        protected string SelectWhere
        {
            get { return _SelectWhere; }
            set { _SelectWhere = value; }
        }

        private Dictionary<string, object> _SelectDic = null;
        /// <summary>
        /// 查询键值对
        /// </summary>
        protected Dictionary<string, object> SelectDic
        {
            get
            {
                if (_SelectDic == null)
                {
                    _SelectDic = new Dictionary<string, object>();
                }
                return _SelectDic;
            }
        }

        protected string _OrderByName = null;
        /// <summary>
        /// 排序字段名
        /// </summary>
        protected string OrderByName
        {
            get
            {
                if (this._OrderByName == null)
                {
                    var _OrderByName = this.Request?.Parameters?.FirstOrDefault(t => "OrderByName".Equals(t.Name));
                    this._OrderByName = _OrderByName == null ? string.Empty : _OrderByName.Value ?? string.Empty;
                }
                return this._OrderByName;
            }
        }
        /// <summary>
        /// 是否倒叙
        /// </summary>
        protected bool IsDesc
        {
            get
            {
                var Desc = this.Request?.Parameters?.FirstOrDefault(t => "IsDesc".Equals(t.Name));
                if (Desc != null)
                {
                    bool.TryParse(Desc.Value, out var result);
                    return result;
                }
                return false;
            }
        }
        /// <summary>
        /// 排序方式
        /// </summary>
        protected string OrderBy
        {
            get
            {
                if (string.IsNullOrEmpty(OrderByName))
                {
                    return null;
                }
                return string.Format("order by {0} {1}", OrderByName, IsDesc ? "Desc" : string.Empty);
            }
        }

        /// <summary>
        /// 设置时间相关参数
        /// </summary>
        /// <param name="DefaultName"></param>
        protected void SetTimeParameter(string DefaultName)
        {
            var StartTime = this.StartTime;
            var EndTime = this.EndTime;
            var OrderByName = string.IsNullOrEmpty(this.OrderByName) ? DefaultName : this.OrderByName;
            if (StartTime != null)
            {
                SelectDic.Add(OrderByName + ">=", StartTime);
            }
            if (EndTime != null)
            {
                SelectDic.Add(OrderByName + "<=", EndTime);
            }
        }
        #endregion

        #region 实现IWebSocketServerAction的相关操作
        /// <inheritdoc/>
        List<MethodHelper> IWebSocketServerAction.MethodList { get; set; }

        /// <inheritdoc/>
        public Fleck.IWebSocketConnection Socket { get; set; }

        /// <inheritdoc/>
        public List<Fleck.IWebSocketConnection> SocketList { get; set; }

        /// <inheritdoc/>
        List<WebSocketFilterAttribute> IWebSocketServerAction.FilterList { get; set; }

        /// <inheritdoc/>
        public object Clone()
        {
            return this.MemberwiseClone();
        }
        #endregion

        /// <inheritdoc/>
        bool IWebSocketServerAction.IsEnd { get; set; }

        /// <summary>
        /// 用于获取正常情况获取不到的参数，方法时使用
        /// </summary>
        public IWebSocketServerAction IWebSocketServer { get { return this; } }

        /// <inheritdoc/>
        public SocketRequest Request { get; set; }

        /// <inheritdoc/>
        public object Result { get; set; }

        /// <inheritdoc/>
        public Exception ExceptionResult { get; set; }

        /// <inheritdoc/>
        public int CacheMaxCount { get; set; }

        /// <inheritdoc/>
        public bool BroadcastMessage(bool Bol, int Status, string Message, object Data)
        {
            return BroadcastMessage(new ResponseResult(Bol)
            {
                Status = Status,
                Message = Message,
                Data = Data
            });
        }

        /// <inheritdoc/>
        public bool BroadcastMessage(ResponseResult responseResult)
        {
            try
            {
                ClearNotOnlineCache(socket => socket.Json(responseResult));
            }
            catch (System.Exception)
            {
                return false;
            }
            return true;
        }

        #region 可供重写的方法
        /// <inheritdoc/>
        public virtual bool CacheBeforeValidate(SocketRequest Request)
        {
            return true;
        }

        /// <inheritdoc/>
        public virtual void CacheClearBefore(string ClassName)
        {
            BroadcastMessage(new ResponseResult
            {
                ClassName = ClassName,
                Message = "缓存被清除",
                Status = 102
            });
        }

        /// <inheritdoc/>
        public virtual void CacheClearAfter(string ClassName)
        {

        }

        /// <inheritdoc/>
        public virtual void CloseAfter(Fleck.IWebSocketConnection Client)
        {

        }
        #endregion

        /// <inheritdoc/>
        public void ClearNotOnlineCache(Action<Fleck.IWebSocketConnection> ClientAction = null)
        {
            int i = 0;
            while (i < SocketList.Count)
            {
                var socket = SocketList[i];
                if (socket.IsAvailable)
                {
                    if (ClientAction != null)
                    {
                        ClientAction(socket);
                    }
                    i++;
                }
                else
                {
                    SocketList.Remove(socket);
                }
            }
        }

        /// <summary>
        /// 通过Ip获取缓存中的客户端
        /// </summary>
        /// <param name="Ip">Ip</param>
        /// <returns></returns>
        public Fleck.IWebSocketConnection GetClient(string Ip)
        {
            var socket = SocketList.FirstOrDefault(t => t.ConnectionInfo.ClientIpAddress.Equals(Ip));
            if (socket == null)
            {
                return null;
            }
            if (socket.IsAvailable)
            {
                return socket;
            }
            SocketList.Remove(socket);
            return null;
        }

        /// <summary>
        /// 获取可被PublicEntity.SocketByteReceive解析的byte[]
        /// </summary>
        /// <param name="Bol">是否成功</param>
        /// <param name="Message">提示消息</param>
        /// <remarks>
        /// 通过此方法获取的类已经添加好了ClassName(类名)、ActionName(方法名)、参数
        /// </remarks>
        /// <returns></returns>
        public PublicEntity.SocketByteSend GetSocketByteSend(bool Bol, string Message = null)
        {
            var sendData = new PublicEntity.SocketByteSend();
            sendData.AddValue("ClassName", Request.ClassName);
            sendData.AddValue("ActionName", Request.ActionName);
            sendData.AddValue("Bol", Bol);
            sendData.AddValue("Message", Message);
            return sendData;
        }

        #region 正常返回
        /// <summary>
        /// 不对客户端输出任何信息
        /// </summary>
        /// <remarks>直接返回null也可以</remarks>
        /// <returns></returns>
        protected SocketResult.SocketNotResult NotResult()
        {
            return null;
            //return new SocketResult.SocketNotResult();
        }

        /// <summary>
        /// 对客户端输出不做任何包装的字符串
        /// </summary>
        /// <param name="Data">数据源</param>
        /// <returns></returns>
        protected SocketResult.SocketStringResult StringResult(string Data)
        {
            return new SocketResult.SocketStringResult(Data);
        }

        /// <summary>
        /// 返回Json类型的字符串
        /// </summary>
        /// <param name="Data">数据源</param>
        /// <returns></returns>
        protected SocketResult.SocketJsonResult JsonResult(object Data)
        {
            return new SocketResult.SocketJsonResult(Data);
        }

        /// <summary>
        /// 返回成功Json类型的字符串
        /// </summary>
        /// <param name="Message">消息</param>
        /// <param name="Data">数据源</param>
        /// <param name="Status">状态</param>
        /// <returns></returns>
        protected SocketResult.SocketJsonResult RError(string Message, object Data = null, int Status = 4000)
        {
            ResponseResult responseResult = new ResponseResult(false)
            {
                Message = Message,
                Data = Data,
                ClassName = Request.ClassName,
                ActionName = Request.ActionName,
                Status = Status
            };
            return new SocketResult.SocketJsonResult(responseResult);
        }

        /// <summary>
        /// 返回失败Json类型的字符串
        /// </summary>
        /// <param name="Message">消息</param>
        /// <param name="Data">数据源</param>
        /// <param name="Status">状态</param>
        /// <returns></returns>
        protected SocketResult.SocketJsonResult RSuccess(string Message, object Data = null, int Status = 1000)
        {
            ResponseResult responseResult = new ResponseResult(true)
            {
                Message = Message,
                Data = Data,
                ClassName = Request.ClassName,
                ActionName = Request.ActionName,
                Status = Status
            };
            return new SocketResult.SocketJsonResult(responseResult);
        }

        /// <summary>
        /// 返回byte数组
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        protected SocketResult.SocketByteResult ByteResult(PublicEntity.SocketByteSend data)
        {
            return new SocketResult.SocketByteResult(data.SendByteArray());
        }

        /// <summary>
        /// 返回文件
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        protected SocketResult.SocketByteResult FileResult(string FileName, byte[] File)
        {
            var data = GetSocketByteSend(true);
            data.AddFile("File", FileName, System.IO.Path.GetExtension(FileName), File);
            return ByteResult(data);
        }

        /// <summary>
        /// 返回文件
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        protected SocketResult.SocketByteResult FileResult(string FileName)
        {
            return FileResult(System.IO.Path.GetFileName(FileName), System.IO.File.ReadAllBytes(FileName));
        }
        #endregion

        #region 拥有类型名称的返回
        /// <summary>
        /// 返回成功Json类型的字符串
        /// </summary>
        /// <param name="webSocket">Socket客户端</param>
        /// <param name="Message">消息</param>
        /// <param name="Data">数据源</param>
        /// <param name="Status">状态</param>
        /// <returns></returns>
        protected void RError(Fleck.IWebSocketConnection webSocket, string Message, object Data = null, int Status = 4000)
        {
            ResponseResult responseResult = new ResponseResult(false)
            {
                Message = Message,
                Data = Data,
                ClassName = Request.ClassName,
                ActionName = Request.ActionName,
                Status = Status
            };
            webSocket.Json(responseResult);
        }

        /// <summary>
        /// 返回失败Json类型的字符串
        /// </summary>
        /// <param name="webSocket">Socket客户端</param>
        /// <param name="Message">消息</param>
        /// <param name="Data">数据源</param>
        /// <param name="Status">状态</param>
        /// <returns></returns>
        protected void RSuccess(Fleck.IWebSocketConnection webSocket, string Message, object Data = null, int Status = 1000)
        {
            ResponseResult responseResult = new ResponseResult(true)
            {
                Message = Message,
                Data = Data,
                ClassName = Request.ClassName,
                ActionName = Request.ActionName,
                Status = Status
            };
            webSocket.Json(responseResult);
        }
        #endregion
    }
}
